#ifndef __OLED_H__
#define __OLED_H__

#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <string.h>

#define I2C_ADDR 0x3c//通过查找I2C设备获得地址

//char DataBuffer[8][128]={0};

 //'0'-48, 'A'-(65-10)55 'a'-(97-36)61
static unsigned char F68[][6] =
{
{0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
{0x00, 0x00, 0x42, 0x7F, 0x40, 0x00},// 1
{0x00, 0x42, 0x61, 0x51, 0x49, 0x46},// 2
{0x00, 0x21, 0x41, 0x45, 0x4B, 0x31},// 3
{0x00, 0x18, 0x14, 0x12, 0x7F, 0x10},// 4
{0x00, 0x27, 0x45, 0x45, 0x45, 0x39},// 5
{0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
{0x00, 0x01, 0x71, 0x09, 0x05, 0x03},// 7
{0x00, 0x36, 0x49, 0x49, 0x49, 0x36},// 8
{0x00, 0x06, 0x49, 0x49, 0x29, 0x1E},// 9

{0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C},// A10
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x36},// B
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x22},// C
{0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C},// D
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x41},// E
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x01},// F
{0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A},// G
{0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F},// H
{0x00, 0x00, 0x41, 0x7F, 0x41, 0x00},// I
{0x00, 0x20, 0x40, 0x41, 0x3F, 0x01},// J
{0x00, 0x7F, 0x08, 0x14, 0x22, 0x41},// K
{0x00, 0x7F, 0x40, 0x40, 0x40, 0x40},// L
{0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F},// M
{0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F},// N
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E},// O
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x06},// P
{0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E},// Q
{0x00, 0x7F, 0x09, 0x19, 0x29, 0x46},// R
{0x00, 0x46, 0x49, 0x49, 0x49, 0x31},// S
{0x00, 0x01, 0x01, 0x7F, 0x01, 0x01},// T
{0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F},// U
{0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F},// V
{0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F},// W
{0x00, 0x63, 0x14, 0x08, 0x14, 0x63},// X
{0x00, 0x07, 0x08, 0x70, 0x08, 0x07},// Y
{0x00, 0x61, 0x51, 0x49, 0x45, 0x43},// Z35

{0x00, 0x20, 0x54, 0x54, 0x54, 0x78},// a36
{0x00, 0x7F, 0x48, 0x44, 0x44, 0x38},// b
{0x00, 0x38, 0x44, 0x44, 0x44, 0x20},// c
{0x00, 0x38, 0x44, 0x44, 0x48, 0x7F},// d
{0x00, 0x38, 0x54, 0x54, 0x54, 0x18},// e
{0x00, 0x08, 0x7E, 0x09, 0x01, 0x02},// f
{0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C},// g
{0x00, 0x7F, 0x08, 0x04, 0x04, 0x78},// h
{0x00, 0x00, 0x44, 0x7D, 0x40, 0x00},// i
{0x00, 0x40, 0x80, 0x84, 0x7D, 0x00},// j
{0x00, 0x7F, 0x10, 0x28, 0x44, 0x00},// k
{0x00, 0x00, 0x41, 0x7F, 0x40, 0x00},// l
{0x00, 0x7C, 0x04, 0x18, 0x04, 0x78},// m
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x78},// n
{0x00, 0x38, 0x44, 0x44, 0x44, 0x38},// o
{0x00, 0xFC, 0x24, 0x24, 0x24, 0x18},// p
{0x00, 0x18, 0x24, 0x24, 0x18, 0xFC},// q
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x08},// r
{0x00, 0x48, 0x54, 0x54, 0x54, 0x20},// s
{0x00, 0x04, 0x3F, 0x44, 0x40, 0x20},// t
{0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C},// u
{0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C},// v
{0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C},// w
{0x00, 0x44, 0x28, 0x10, 0x28, 0x44},// x
{0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C},// y
{0x00, 0x44, 0x64, 0x54, 0x4C, 0x44},// z61

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// sp62
};



void WriteCmd(int fd, unsigned char I2C_Command)//写命令
{
	wiringPiI2CWriteReg8(fd, 0x00, I2C_Command);
	//往0x00寄存器写入数据，数据为命令
}
 

void WriteData(int fd, unsigned char I2C_Data)//写数据
{
    wiringPiI2CWriteReg8(fd, 0x40, I2C_Data);
    //往0x40寄存器写入数据，数据为图像信息
}

void OLED_SetPos(int fd, unsigned char x, unsigned char y) //设置起始点坐标
{
//    WriteCmd(fd, (unsigned char)(0x40 + x));  /*设置开始行*/

    WriteCmd(fd, (unsigned char)(0xb0 + y));  /*设置开始页*/
    WriteCmd(fd, ((x & 0x0f) | 0x00));//LOW
    WriteCmd(fd, (((x & 0xf0) >> 4) | 0x10));//HIGHT
}

void OLED_Char(int fd, unsigned char x, unsigned char y, char curChar)
{

    OLED_SetPos(fd,x,y);

    if(curChar>='0'&&curChar<='9')
    {
        for (int i=0;i<6;++i) {
            WriteData(fd,F68[curChar-48][i]);
        }
    }
    else{
        if(curChar>='A'&&curChar<='Z')
        {
            for (int i=0;i<6;++i) {
                WriteData(fd,F68[curChar-55][i]);
            }
        }
        else{
            if(curChar>='a'&&curChar<='z')
            {
                for (int i=0;i<6;++i) {
                    WriteData(fd,F68[curChar-61][i]);
                }
            }else {
                if(curChar == 32){//空格
                    for (int i=0;i<6;++i) {
                        WriteData(fd,F68[62][i]);
                    }
                }
            }
        }
    }
}

void OLED_String(int fd, unsigned char x, unsigned char y,char* string)
{
    for(int i=0; string[i]!='\0';++i)
    OLED_Char( fd, x, y, string[i]);
}
 
void OLED_Init(int fd)
{
 
	WriteCmd(fd, 0xAE); //display off
 
	WriteCmd(fd, 0x20);	//Set Memory Addressing Mode	   /*默认0x02，从左向右刷新 */
 
	WriteCmd(fd, 0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	
	WriteCmd(fd, 0xb0);	//Set Page Start Address for Page Addressing Mode,0-7
	
	WriteCmd(fd, 0xc8);	//Set COM Output Scan Direction
 
	WriteCmd(fd, 0x00); //---set low column address /*起始位置低位列0x00~0x0f */
 
	WriteCmd(fd, 0x10); //---set high column address /*起始位置高位列0x10~0x1f */
 
	WriteCmd(fd, 0x40); //--set start line address  /*起始行0x40~0x7F  正好是0~63*/
 
	WriteCmd(fd, 0x81); //--set contrast control register
	WriteCmd(fd, 0xff); //亮度调节 0x00~0xff
 
	WriteCmd(fd, 0xa1); //--set segment re-map 0 to 127
 
	WriteCmd(fd, 0xa6); //--set normal display
 
	WriteCmd(fd, 0xa8); //--set multiplex ratio(1 to 64)
	WriteCmd(fd, 0x3F); // /*设置页，0x3f为默认，有效值为0~14 */
 
	WriteCmd(fd, 0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	
	WriteCmd(fd, 0xd3); //-set display offset
	WriteCmd(fd, 0x00); //-not offset 0x00为默认
 
	WriteCmd(fd, 0xd5); //--set display clock divide ratio/oscillator frequency
	WriteCmd(fd, 0xf0); //--set divide ratio
 
	WriteCmd(fd, 0xd9); //--set pre-charge period
	WriteCmd(fd, 0x22); //
 
	WriteCmd(fd, 0xda); //--set com pins hardware configuration
	WriteCmd(fd, 0x12);
 
	WriteCmd(fd, 0xdb); //--set vcomh
	WriteCmd(fd, 0x20); //0x20,0.77xVcc 默认
 
	WriteCmd(fd, 0x8d); //--set DC-DC enable  
	WriteCmd(fd, 0x14); //  0x14 enable  0x10 disabled（sleep）  一般用于交流电设置
 
	WriteCmd(fd, 0xAF); //--turn on oled panel
}
 
 void OLED_DisplayOff(int fd)
 {
	WriteCmd(fd,0x8D); 
	WriteCmd(fd,0x10); 
    WriteCmd(fd,0xAE);
 }
 
  void OLED_DisplayOn(int fd)
 {
	WriteCmd(fd,0x8D); 
	WriteCmd(fd,0x14); 
	WriteCmd(fd,0xAF); 
 }
 
void OLED_CLR(int fd)//清屏
{
 OLED_SetPos(fd,0,0);
 for (int i=0;i<8;++i) {
     for (int j=0;j<128;++j) {
         WriteData(fd,0x00);
     }
 }

}
 #endif
